home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_084 / requester / requester.c next >
C/C++ Source or Header  |  1992-05-06  |  35KB  |  1,122 lines

  1. /****************************************************************************
  2.  *
  3.  *  FileRequest() - File Name Requester
  4.  *
  5.  *  By Kevin Lee Clague
  6.  *     408 Tortolla Way
  7.  *     San Jose, Ca 95033
  8.  *     408-258-9891       work 408-737-5481
  9.  *
  10.  *  Copyright (C) 1986. All rights reserved.
  11.  *
  12.  *  This program is freely distributable as long as this copyright notice
  13.  *  is retained. It intended for personal, non-commercial use.
  14.  *
  15.  *  This file name requester is modeled after Deluxe Paints file name
  16.  *  requester. The dimensions/locations of all borders, gadgets and text were
  17.  *  arrived at empirically. Besides being a great program, Deluxe Paint is a
  18.  *  trade mark of Electronics Arts.
  19.  *
  20.  *  The knowledge on how to get at the entries in the directories was drawn
  21.  *  from Mike (I'll be melow when I'm dead) Meyer's "Browser".
  22.  *
  23.  ***************************************************************************/
  24.  
  25. /***************************************************************************
  26.  *
  27.  *  Things to do:
  28.  *    1. Dynamically allocate space for file name strings as they are gotten
  29.  *       from the disk, rather than static allocation of them in arrays.
  30.  *    2. Fence off intuition events while getting file names from disk
  31.  *       directory (and put up the zz sleepy cloud in place of the arrow
  32.  *       mouse cursor.)
  33.  *    3. Be a little more diligent with my use of RefreshGadgets.
  34.  *
  35.  ***************************************************************************/
  36.  
  37. /***************************************************************************
  38.  *
  39.  *   Changes made by:       Randy Finch
  40.  *                          122 West Oak Hill Dr.
  41.  *                          Florence, AL 35630
  42.  *
  43.  *                       Phone -     Day: 205-386-2252
  44.  *                               Evening: 205-767-3528
  45.  *    BIX name: rfinch
  46.  *
  47.  *
  48.  *  1. Eliminated RemoveGadgets() and AddGadgets() so it would work under
  49.  *     AmigaDOS 1.2.
  50.  *  2. Made changes to allow compilation with Lattice.
  51.  *  3. Changed Requester gadgetry to look more like DPaint II.
  52.  *  4. Modified how the proportional gadget is handled.  It now conforms
  53.  *     to the method shown in the Enhancer booklet.
  54.  *  5. Added "/ Parent (dir)" as the first listing in the boolean file
  55.  *     selection gadgets.
  56.  *  6. Added three new boolean gadgets: df0:, df1:, and hd: for selecting
  57.  *     drives quickly.  The hd: device is a special gadget.  It can be
  58.  *     modified by the user.  If the user types his own device into the
  59.  *     Drawer string gadget directly, and it does not match either
  60.  *     df0: or df1:, it will assign this device name to the hd: gadget
  61.  *     (or as I call it, the user gadget).  Thus, if your hard disk is
  62.  *     called dh0:, type this in the Drawer gadget.  When you select
  63.  *     Load or Cancel, this will be assigned to the user gadget.  The next
  64.  *     time the requester is called up, dh0: will appear in the gadget.
  65.  *     NOTE:  The device name including the colon must be 8 characters
  66.  *            or less.
  67.  *  7. The Drawer string now shows the entire path rather than just the
  68.  *     current directory.
  69.  *  8. The function FileRequest() now accepts an additional parameter,
  70.  *     FileExtention.  This allows the function to be called specifying
  71.  *     an extension for the listed filenames.  If a file (does not include
  72.  *     directorys) does not have this extension, it will not be listed
  73.  *     in the file selection gadgets.
  74.  *
  75.  *
  76.  *  Additional notes: The function rindex(), which is used extensively in
  77.  *                    this routine, is not in the Lattice library.  I
  78.  *                    wrote my own version.  It simply returns a pointer
  79.  *                    to the right-most occurance of a character in a
  80.  *                    string.
  81.  *                    Make sure the string you assign for the full path
  82.  *                    name is long enough to handle the maximum path
  83.  *                    you believe the user will need.
  84.  *
  85.  *************************************************************************/
  86.  
  87. #include "Requester.h"
  88.  
  89. extern struct IntuitionBase *IntuitionBase;
  90.  
  91. BOOL IsDir(), IsParent();
  92. BOOL WaitRequester();
  93. void InitFNR(), SetNewDrawer(), SetNewFile(), ListDir(), AttachList();
  94. void ScrollList(), PotScrollList(), ThrowTrailing(), GoParent();
  95. void ChangeDevice(), ToUpper();
  96.  
  97. struct Requester FileRequester;
  98.  
  99. UBYTE *FRFullPath;
  100. struct IntuiMessage *message;
  101. struct Window *FRWindow;
  102.  
  103. struct FileInfoBlock FileInfo;
  104. USHORT FileCount;                     /* Number of files in current dir */
  105. UBYTE  FileListEntry[MAXFILES][40];   /* File (dir) names in current dir */
  106. TEXT   GetUser[80];
  107. TEXT   spaces30[] = "                              ";
  108. UBYTE *FileExt;
  109.  
  110. USHORT FirstFile;
  111.  
  112. #define PATHNAMELEN 80
  113. #define MIN(a,b)    ((a)<(b)?(a):(b))
  114.  
  115. /****************************************************************************
  116.  *                The Gadget String
  117.  ***************************************************************************/
  118. /******************************
  119.  * The File Name Gadget stuff *
  120.  *****************************/
  121. struct IntuiText FileText =
  122.   {
  123.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  124.   -46,0,                  /* LeftEdge,TopEdge */
  125.   NULL,                   /* ITextFont */
  126.   "File:",                /* IText */
  127.   NULL                    /* NextText */
  128.   };
  129.  
  130. UBYTE FileName[40];
  131. UBYTE Backup[40];
  132. struct StringInfo FileString = {
  133.     &FileName,               /* Buffer */
  134.     &Backup,                 /* UndoBuffer */
  135.     0,                       /* BufferPos */
  136.     32,                      /* MaxChars  */
  137.     0,                       /* DispPos */
  138.     0,0,0,0,0,NULL,0,NULL    /* maintained by Intuition */
  139.   };
  140.  
  141. struct Gadget FileGadget =
  142.   { /* File string */
  143.   NULL,                    /* NextGadget */
  144.   67,113,                  /* LeftEdge, TopEdge */
  145.   185,8,                   /* Width, Height */
  146.   GADGHCOMP,               /* Flags */
  147.   0,                       /* Activation */
  148.   STRGADGET|REQGADGET,     /* GadgetType */
  149.   NULL,                    /* GadgetRender */
  150.   NULL,                    /* SelectRender */
  151.   &FileText,               /* GadgetText */
  152.   0,                       /* MutualExclude */
  153.   &FileString,             /* SpecialInfo */
  154.   NULL,                    /* GadgetID */
  155.   NULL                     /* UserData */
  156.   };
  157.  
  158. /********************************
  159.  * The Drawer Name Gadget stuff *
  160.  *******************************/
  161. struct IntuiText DrawerText =
  162.   {
  163.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  164.   -62,0,                  /* LeftEdge,TopEdge */
  165.   NULL,                   /* ITextFont */
  166.   "Drawer:",              /* IText */
  167.   NULL                    /* NextText */
  168.   };
  169.  
  170. UBYTE DrawerName[80];
  171. UBYTE Backup2[80];
  172. struct StringInfo DrawerString = {
  173.     &DrawerName,             /* Buffer */
  174.     &Backup2,                /* UndoBuffer */
  175.     0,                       /* BufferPos */
  176.     80,                      /* MaxChars  */
  177.     0,                       /* DispPos*/
  178.     0,0,0,0,0,NULL,0,NULL    /* maintained by Intuition*/
  179.   };
  180.  
  181. struct Gadget DrawerGadget =
  182.   { /* Drawer string */
  183.   &FileGadget,             /* NextGadget */
  184.   67,98,                   /* LeftEdge, TopEdge */
  185.   185,8,                   /* Width, Height */
  186.   GADGHCOMP,               /* Flags */
  187.   RELVERIFY,               /* Activation */
  188.   STRGADGET|REQGADGET,     /* GadgetType */
  189.   NULL,                    /* GadgetRender */
  190.   NULL,                    /* SelectRender */
  191.   &DrawerText,             /* GadgetText */
  192.   0,                       /* MutualExclude */
  193.   &DrawerString,           /* SpecialInfo */
  194.   DRAWERGADGET,            /* GadgetID */
  195.   NULL                     /* UserData */
  196.   };
  197.  
  198. /****************************************
  199.  * The File list selection Gadget stuff *
  200.  ***************************************/
  201. UBYTE PickNames[8][40];
  202. struct IntuiText FileList[] =
  203.   {
  204.     {
  205.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  206.     0,0,                    /* LeftEdge,TopEdge */
  207.     NULL,                   /* ITextFont */
  208.     &PickNames[0][0],       /* IText */
  209.     NULL                    /* NextText */
  210.     },
  211.     {
  212.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  213.     0,0,                    /* LeftEdge,TopEdge */
  214.     NULL,                   /* ITextFont */
  215.     &PickNames[1][0],       /* IText */
  216.     NULL                    /* NextText */
  217.     },
  218.     {
  219.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  220.     0,0,                    /* LeftEdge,TopEdge */
  221.     NULL,                   /* ITextFont */
  222.     &PickNames[2][0],       /* IText */
  223.     NULL                    /* NextText */
  224.     },
  225.     {
  226.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  227.     0,0,                    /* LeftEdge,TopEdge */
  228.     NULL,                   /* ITextFont */
  229.     &PickNames[3][0],       /* IText */
  230.     NULL                    /* NextText */
  231.     },
  232.     {
  233.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  234.     0,0,                    /* LeftEdge,TopEdge */
  235.     NULL,                   /* ITextFont */
  236.     &PickNames[4][0],       /* IText */
  237.     NULL                    /* NextText */
  238.     },
  239.     {
  240.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  241.     0,0,                    /* LeftEdge,TopEdge */
  242.     NULL,                   /* ITextFont */
  243.     &PickNames[5][0],       /* IText */
  244.     NULL                    /* NextText */
  245.     },
  246.     {
  247.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  248.     0,0,                    /* LeftEdge,TopEdge */
  249.     NULL,                   /* ITextFont */
  250.     &PickNames[6][0],       /* IText */
  251.     NULL                    /* NextText */
  252.     },
  253.     {
  254.     0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  255.     0,0,                    /* LeftEdge,TopEdge */
  256.     NULL,                   /* ITextFont */
  257.     &PickNames[7][0],       /* IText */
  258.     NULL                    /* NextText */
  259.     }
  260.   };
  261.  
  262. struct Gadget FileListGadget[] =
  263.   {
  264.     { /* File name selection 0 */
  265.     &FileListGadget[1],      /* NextGadget */
  266.     5,14,                    /* LeftEdge, TopEdge */
  267.     244,8,                   /* Width, Height */
  268.     GADGHNONE,               /* Flags */
  269.     GADGIMMEDIATE,           /* Activation */
  270.     BOOLGADGET|REQGADGET,    /* GadgetType */
  271.     NULL,                    /* GadgetRender */
  272.     NULL,                    /* SelectRender */
  273.     &FileList[0],            /* GadgetText */
  274.     0,                       /* MutualExclude */
  275.     NULL,                    /* SpecialInfo */
  276.     FILE0GADGET,             /* GadgetID */
  277.     NULL                     /* UserData */
  278.     },
  279.     { /* File name selection 1 */
  280.     &FileListGadget[2],      /* NextGadget */
  281.     5,24,                    /* LeftEdge, TopEdge */
  282.     244,8,                   /* Width, Height */
  283.     GADGHNONE,               /* Flags */
  284.     GADGIMMEDIATE,           /* Activation */
  285.     BOOLGADGET|REQGADGET,    /* GadgetType */
  286.     NULL,                    /* GadgetRender */
  287.     NULL,                    /* SelectRender */
  288.     &FileList[1],            /* GadgetText */
  289.     0,                       /* MutualExclude */
  290.     NULL,                    /* SpecialInfo */
  291.     FILE1GADGET,             /* GadgetID */
  292.     NULL                     /* UserData */
  293.     },
  294.     { /* File name selection 2 */
  295.     &FileListGadget[3],      /* NextGadget */
  296.     5,34,                    /* LeftEdge, TopEdge */
  297.     244,8,                   /* Width, Height */
  298.     GADGHNONE,               /* Flags */
  299.     GADGIMMEDIATE,           /* Activation */
  300.     BOOLGADGET|REQGADGET,    /* GadgetType */
  301.     NULL,                    /* GadgetRender */
  302.     NULL,                    /* SelectRender */
  303.     &FileList[2],            /* GadgetText */
  304.     0,                       /* MutualExclude */
  305.     NULL,                    /* SpecialInfo */
  306.     FILE2GADGET,             /* GadgetID */
  307.     NULL                     /* UserData */
  308.     },
  309.     { /* File name selection 3 */
  310.     &FileListGadget[4],      /* NextGadget */
  311.     5,44,                    /* LeftEdge, TopEdge */
  312.     244,8,                   /* Width, Height */
  313.     GADGHNONE,               /* Flags */
  314.     GADGIMMEDIATE,           /* Activation */
  315.     BOOLGADGET|REQGADGET,    /* GadgetType */
  316.     NULL,                    /* GadgetRender */
  317.     NULL,                    /* SelectRender */
  318.     &FileList[3],            /* GadgetText */
  319.     0,                       /* MutualExclude */
  320.     NULL,                    /* SpecialInfo */
  321.     FILE3GADGET,             /* GadgetID */
  322.     NULL                     /* UserData */
  323.     },
  324.     { /* File name selection 4 */
  325.     &FileListGadget[5],      /* NextGadget */
  326.     5,54,                    /* LeftEdge, TopEdge */
  327.     244,8,                   /* Width, Height */
  328.     GADGHNONE,               /* Flags */
  329.     GADGIMMEDIATE,           /* Activation */
  330.     BOOLGADGET|REQGADGET,    /* GadgetType */
  331.     NULL,                    /* GadgetRender */
  332.     NULL,                    /* SelectRender */
  333.     &FileList[4],            /* GadgetText */
  334.     0,                       /* MutualExclude */
  335.     NULL,                    /* SpecialInfo */
  336.     FILE4GADGET,             /* GadgetID */
  337.     NULL                     /* UserData */
  338.     },
  339.     { /* File name selection 5 */
  340.     &FileListGadget[6],      /* NextGadget */
  341.     5,64,                    /* LeftEdge, TopEdge */
  342.     244,8,                   /* Width, Height */
  343.     GADGHNONE,               /* Flags */
  344.     GADGIMMEDIATE,           /* Activation */
  345.     BOOLGADGET|REQGADGET,    /* GadgetType */
  346.     NULL,                    /* GadgetRender */
  347.     NULL,                    /* SelectRender */
  348.     &FileList[5],            /* GadgetText */
  349.     0,                       /* MutualExclude */
  350.     NULL,                    /* SpecialInfo */
  351.     FILE5GADGET,             /* GadgetID */
  352.     NULL                     /* UserData */
  353.     },
  354.     { /* File name selection 6 */
  355.     &FileListGadget[7],      /* NextGadget */
  356.     5,74,                    /* LeftEdge, TopEdge */
  357.     244,8,                   /* Width, Height */
  358.     GADGHNONE,               /* Flags */
  359.     GADGIMMEDIATE,           /* Activation */
  360.     BOOLGADGET|REQGADGET,    /* GadgetType */
  361.     NULL,                    /* GadgetRender */
  362.     NULL,                    /* SelectRender */
  363.     &FileList[6],            /* GadgetText */
  364.     0,                       /* MutualExclude */
  365.     NULL,                    /* SpecialInfo */
  366.     FILE6GADGET,             /* GadgetID */
  367.     NULL                     /* UserData */
  368.     },
  369.     { /* File name selection 7 */
  370.     &DrawerGadget,           /* NextGadget */
  371.     5,84,                    /* LeftEdge, TopEdge */
  372.     244,8,                   /* Width, Height */
  373.     GADGHNONE,               /* Flags */
  374.     GADGIMMEDIATE,           /* Activation */
  375.     BOOLGADGET|REQGADGET,    /* GadgetType */
  376.     NULL,                    /* GadgetRender */
  377.     NULL,                    /* SelectRender */
  378.     &FileList[7],            /* GadgetText */
  379.     0,                       /* MutualExclude */
  380.     NULL,                    /* SpecialInfo */
  381.     FILE7GADGET,             /* GadgetID */
  382.     NULL                     /* UserData */
  383.     }
  384.   };
  385. /********************************
  386.  * The Load Button gadget stuff *
  387.  *******************************/
  388. SHORT ButtonPoints1[] =
  389.   {
  390.   -2, 11,
  391.   66, 11,
  392.   66, -1
  393.   };
  394. struct Border ButtonBorder1 =
  395.   {
  396.   0,0,
  397.   0,1,JAM1,
  398.   3,
  399.   &ButtonPoints1[0],
  400.   NULL
  401.   };
  402. SHORT ButtonPoints0[] =
  403.   {
  404.   -3, -2,
  405.   65, -2,
  406.   65, 10,
  407.   -3, 10,
  408.   -3, -2
  409.   };
  410. struct Border ButtonBorder0 =
  411.   {
  412.   0,0,
  413.   0,1,JAM1,
  414.   5,
  415.   &ButtonPoints0[0],
  416.   &ButtonBorder1
  417.   };
  418.  
  419. struct IntuiText LoadText =
  420.   {
  421.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  422.   0,0,                    /* LeftEdge,TopEdge */
  423.   NULL,                   /* ITextFont */
  424.   NULL,                   /* IText */
  425.   NULL                    /* NextText */
  426.   };
  427.  
  428. struct Gadget LoadGadget =
  429.   { /* Load button */
  430.   &FileListGadget[0],      /* NextGadget */
  431.   14,148,                  /* LeftEdge, TopEdge */
  432.   64,8,                    /* Width, Height */
  433.   GADGHCOMP,               /* Flags */
  434.   GADGIMMEDIATE|ENDGADGET, /* Activation */
  435.   BOOLGADGET|REQGADGET,    /* GadgetType */
  436.   (APTR) &ButtonBorder0,   /* GadgetRender */
  437.   NULL,                    /* SelectRender */
  438.   &LoadText,               /* GadgetText */
  439.   0,                       /* MutualExclude */
  440.   NULL,                    /* SpecialInfo */
  441.   LOADGADGET,              /* GadgetID */
  442.   NULL                     /* UserData */
  443.   };
  444.  
  445. /**********************************
  446.  * The Cancel Button gadget stuff *
  447.  *********************************/
  448. struct IntuiText CancelText =
  449.   {
  450.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  451.   0,0,                    /* LeftEdge,TopEdge */
  452.   NULL,                   /* ITextFont */
  453.   "Cancel",               /* IText */
  454.   NULL                    /* NextText */
  455.   };
  456.  
  457. struct Gadget CancelGadget =
  458.   { /* Cancel button */
  459.   &LoadGadget,             /* NextGadget */
  460.   187,148,                 /* LeftEdge, TopEdge */
  461.   64,8,                    /* Width, Height */
  462.   GADGHCOMP,               /* Flags */
  463.   GADGIMMEDIATE|ENDGADGET, /* Activation */
  464.   BOOLGADGET|REQGADGET,    /* GadgetType */
  465.   (APTR) &ButtonBorder0,   /* GadgetRender */
  466.   NULL,                    /* SelectRender */
  467.   &CancelText,             /* GadgetText */
  468.   0,                       /* MutualExclude */
  469.   NULL,                    /* SpecialInfo */
  470.   CANCELGADGET,            /* GadgetID */
  471.   NULL                     /* UserData */
  472.   };
  473.  
  474.  
  475. /******************************************
  476.  * The DF0:, DF1:, and User Button Gadget *
  477.  ******************************************/
  478.  
  479. struct IntuiText DF0Text =
  480.   {
  481.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  482.   0,0,                    /* LeftEdge,TopEdge */
  483.   NULL,                   /* ITextFont */
  484.   "DF0:",                 /* IText */
  485.   NULL                    /* NextText */
  486.   };
  487.  
  488. struct IntuiText DF1Text =
  489.   {
  490.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  491.   0,0,                    /* LeftEdge,TopEdge */
  492.   NULL,                   /* ITextFont */
  493.   "DF1:",                 /* IText */
  494.   NULL                    /* NextText */
  495.   };
  496.  
  497. struct IntuiText UserText =
  498.   {
  499.   0,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  500.   0,0,                    /* LeftEdge,TopEdge */
  501.   NULL,                   /* ITextFont */
  502.   "HD:     ",             /* IText */
  503.   NULL                    /* NextText */
  504.   };
  505.  
  506. struct Gadget DFGadget[] =
  507.   {
  508.   {
  509.   &CancelGadget,           /* NextGadget */
  510.   14,130,                  /* LeftEdge, TopEdge */
  511.   64,8,                    /* Width, Height */
  512.   GADGHNONE,               /* Flags */
  513.   RELVERIFY,               /* Activation */
  514.   BOOLGADGET|REQGADGET,    /* GadgetType */
  515.   (APTR) &ButtonBorder0,   /* GadgetRender */
  516.   NULL,                    /* SelectRender */
  517.   &DF0Text,                /* GadgetText */
  518.   0,                       /* MutualExclude */
  519.   NULL,                    /* SpecialInfo */
  520.   DF0GADGET,               /* GadgetID */
  521.   NULL                     /* UserData */
  522.   },
  523.   {
  524.   &DFGadget[0],            /* NextGadget */
  525.   101,130,                 /* LeftEdge, TopEdge */
  526.   64,8,                    /* Width, Height */
  527.   GADGHNONE,               /* Flags */
  528.   RELVERIFY,               /* Activation */
  529.   BOOLGADGET|REQGADGET,    /* GadgetType */
  530.   (APTR) &ButtonBorder0,   /* GadgetRender */
  531.   NULL,                    /* SelectRender */
  532.   &DF1Text,                /* GadgetText */
  533.   0,                       /* MutualExclude */
  534.   NULL,                    /* SpecialInfo */
  535.   DF1GADGET,               /* GadgetID */
  536.   NULL                     /* UserData */
  537.   },
  538.   {
  539.   &DFGadget[1],            /* NextGadget */
  540.   187,130,                 /* LeftEdge, TopEdge */
  541.   64,8,                    /* Width, Height */
  542.   GADGHNONE,               /* Flags */
  543.   RELVERIFY,               /* Activation */
  544.   BOOLGADGET|REQGADGET,    /* GadgetType */
  545.   (APTR) &ButtonBorder0,   /* GadgetRender */
  546.   NULL,                    /* SelectRender */
  547.   &UserText,               /* GadgetText */
  548.   0,                       /* MutualExclude */
  549.   NULL,                    /* SpecialInfo */
  550.   USERGADGET,              /* GadgetID */
  551.   NULL                     /* UserData */
  552.   } };
  553.  
  554.  
  555. /***********************************************
  556.  * The Scroll Selection List up (arrow) gadget *
  557.  **********************************************/
  558. UWORD UpArrowData[15] = {
  559.    0xfffc,
  560.    0xfcfc,
  561.    0xf87c,
  562.    0xf03c,
  563.    0xe01c,
  564.    0xc00c,
  565.    0x8004,
  566.    0xfcfc,
  567.    0xfcfc,
  568.    0xfcfc,
  569.    0xfcfc,
  570.    0xfcfc,
  571.    0xfcfc,
  572.    0xfffc
  573. };
  574.  
  575. struct Image UpArrow =
  576.   {
  577.    0,0,
  578.    14,
  579.    14,
  580.    1,
  581.    &UpArrowData[0],
  582.    0x1, 0x0,
  583.    NULL
  584.    };
  585.  
  586. struct Gadget UpGadget =
  587.   { /* Up a file gadget */
  588.   &DFGadget[2],            /* NextGadget */
  589.   247,13,                  /* LeftEdge, TopEdge */
  590.   12,15,                   /* Width, Height */
  591.   GADGIMAGE|GADGHNONE,     /* Flags */
  592.   GADGIMMEDIATE,           /* Activation */
  593.   BOOLGADGET|REQGADGET,    /* GadgetType */
  594.   (APTR) &UpArrow,         /* GadgetRender */
  595.   NULL,                    /* SelectRender */
  596.   NULL,                    /* GadgetText */
  597.   0,                       /* MutualExclude */
  598.   NULL,                    /* SpecialInfo */
  599.   UPGADGET,                /* GadgetID */
  600.   NULL                     /* UserData */
  601.   };
  602. /*************************************************
  603.  * The Scroll Selection List down (arrow) gadget *
  604.  ************************************************/
  605. UWORD DownArrowData[15] = {
  606.    0xfffc,
  607.    0xfcfc,
  608.    0xfcfc,
  609.    0xfcfc,
  610.    0xfcfc,
  611.    0xfcfc,
  612.    0xfcfc,
  613.    0x8004,
  614.    0xc00c,
  615.    0xe01c,
  616.    0xf03c,
  617.    0xf87c,
  618.    0xfcfc,
  619.    0xfffc
  620. };
  621.  
  622. struct Image DownArrow =
  623.   {
  624.    0,0,
  625.    14,
  626.    14,
  627.    1,
  628.    &DownArrowData[0],
  629.    0x1, 0x0,
  630.    NULL
  631.    };
  632.  
  633. struct Gadget DownGadget =
  634.   { /* Down a file gadget */
  635.   &UpGadget,               /* NextGadget */
  636.   247,79,                  /* LeftEdge, TopEdge */
  637.   12,15,                   /* Width, Height */
  638.   GADGIMAGE|GADGHNONE,     /* Flags */
  639.   GADGIMMEDIATE,           /* Activation */
  640.   BOOLGADGET|REQGADGET,    /* GadgetType */
  641.   (APTR) &DownArrow,       /* GadgetRender */
  642.   NULL,                    /* SelectRender */
  643.   NULL,                    /* GadgetText */
  644.   0,                       /* MutualExclude */
  645.   NULL,                    /* SpecialInfo */
  646.   DOWNGADGET,              /* GadgetID */
  647.   NULL                     /* UserData */
  648.   };
  649.  
  650. /***************************************************
  651.  * The Scroll Selection list up down Potentiometer *
  652.  **************************************************/
  653. struct PropInfo KnobInfo =
  654.   {
  655.   AUTOKNOB | FREEVERT | PROPBORDERLESS,
  656.   0,
  657.   0, /* VertPot */
  658.   0,
  659.   0x7fff, /* VertBody */
  660.   0,0,0,0,0,0
  661.   };
  662.  
  663. struct Image KnobImage =
  664.   {
  665.   0,0,
  666.   0,0,0,
  667.   NULL,
  668.   0,0,
  669.   NULL
  670.   };
  671.  
  672. struct Gadget PotGadget =
  673.   { /* Potentiometer file gadget */
  674.   &DownGadget,             /* NextGadget */
  675.   247,28,                  /* LeftEdge, TopEdge */
  676.   14,50,                   /* Width, Height */
  677.   GADGHNONE,               /* Flags */
  678.   RELVERIFY,               /* Activation */
  679.   PROPGADGET|REQGADGET,    /* GadgetType */
  680.   (APTR) &KnobImage,       /* GadgetRender */
  681.   NULL,                    /* SelectRender */
  682.   NULL,                    /* GadgetText */
  683.   0,                       /* MutualExclude */
  684.   &KnobInfo,               /* SpecialInfo */
  685.   POTGADGET,               /* GadgetID */
  686.   NULL                     /* UserData */
  687.   };
  688. /***************************************************************************
  689. *                  Other Requester structures                              *
  690. ***************************************************************************/
  691. struct IntuiText HeadingText =
  692.   {
  693.   2,1, JAM2,              /* FrontPen, BackPen, DrawMode */
  694.   4,3,                    /* LeftEdge,TopEdge */
  695.   NULL,                   /* ITextFont */
  696.   NULL,                   /* IText */
  697.   NULL                    /* NextText */
  698.   };
  699.  
  700. SHORT Requester0Points[] = {
  701.   2,1,
  702.   261,1,
  703.   261,162,
  704.   2,162,
  705.   2,1
  706.   };
  707. struct Border Requester0Border = {
  708.   0,0,
  709.   0,1,JAM1,
  710.   5,
  711.   &Requester0Points[0],
  712.   NULL
  713.   };
  714.  
  715. SHORT Requester1Points[] = {
  716.   2,12,
  717.   261,12
  718.   };
  719. struct Border Requester1Border = {
  720.   0,0,
  721.   0,1,JAM1,
  722.   2,
  723.   &Requester1Points[0],
  724.   &Requester0Border
  725.   };
  726.  
  727. SHORT Requester2Points[] = {
  728.   2,93,
  729.   261,93
  730.   };
  731. struct Border Requester2Border = {
  732.   0,0,
  733.   0,1,JAM1,
  734.   2,
  735.   &Requester2Points[0],
  736.   &Requester1Border
  737.   };
  738.  
  739. SHORT Requester3Points[] = {
  740.   246,12,
  741.   246,93,
  742.   246,78,
  743.   261,78,
  744.   261,27,
  745.   247,27
  746.   };
  747. struct Border Requester3Border = {
  748.   0,0,
  749.   0,1,JAM1,
  750.   6,
  751.   &Requester3Points[0],
  752.   &Requester2Border
  753.   };
  754.  
  755. /****************************************************************************
  756.  *                     The Code part of the requester
  757.  ***************************************************************************/
  758. BOOL FileRequest(FileType,Action,FullName,window,FileExtension)
  759.   UBYTE *FileType;
  760.   UBYTE *Action;
  761.   UBYTE *FullName;
  762.   struct Window *window;
  763.   UBYTE *FileExtension;
  764. {
  765.   UBYTE *StrPtr;
  766.   BOOL   RetCode;
  767.  
  768.   FRFullPath = FullName;
  769.   FRWindow = window;
  770.   FileExt = FileExtension;
  771.   HeadingText.IText = FileType; /* Center requester title */
  772.   HeadingText.LeftEdge = (256-IntuiTextLength(&HeadingText))/2;
  773.   LoadText.IText = Action;
  774.  
  775.   InitFNR();
  776.  
  777.   /* Separate the path from the file name. Set the file name in the gadget */
  778.   if (StrPtr = rindex(FRFullPath,'/'))
  779.     {
  780.     strcpy(FileString.Buffer,StrPtr + 1);
  781.     *StrPtr = '\0';
  782.     }
  783.   else
  784.     if (StrPtr = rindex(FRFullPath,':'))
  785.       {
  786.       strcpy(FileString.Buffer,StrPtr + 1);
  787.       *(StrPtr+1) = '\0';
  788.       }
  789.     else
  790.       {
  791.       *FileString.Buffer   = '\0';
  792.       *DrawerString.Buffer = '\0';
  793.       *FRFullPath = '\0';
  794.       }
  795.   strcpy(DrawerString.Buffer,FRFullPath);
  796.  
  797.   /* Put up the requester and list the dir into it */
  798.   Request(&FileRequester,FRWindow);
  799.   ListDir(FRFullPath);
  800.   SetNewFile(&FileGadget,FileString.Buffer); /* why do I have to do this? */
  801.   SetNewFile(&DrawerGadget,DrawerString.Buffer);
  802.  
  803.   RetCode = WaitRequester();         /* do everything till Cancel or Load */
  804.  
  805.   /* Put file name and path back together */
  806.   if (FRFullPath[strlen(FRFullPath)-1] != ':')
  807.     strcat(FRFullPath,"/");
  808.   strcat(FRFullPath,FileString.Buffer);
  809.  
  810.   /* Put new user device in device gadget */
  811.   strcpy(GetUser, FRFullPath);
  812.   if (StrPtr = rindex(GetUser, ':'))
  813.      {
  814.      *(StrPtr+1) = '\0';
  815.      ToUpper(GetUser);
  816.      if (strcmp(GetUser,DF0Text.IText) != 0 && strcmp(GetUser,DF1Text.IText) != 0 && strlen(GetUser) <= 8)
  817.         strcpy(UserText.IText, GetUser);
  818.      }
  819.   return(RetCode);
  820. } /* LoadRequest */
  821.  
  822. /*
  823.  *  Init the file name requester
  824.  */
  825. void InitFNR()
  826. {
  827.   InitRequester(&FileRequester);
  828.   FileRequester.LeftEdge  = 6;
  829.   FileRequester.TopEdge   = 12;
  830.   FileRequester.Width     = 264;
  831.   FileRequester.Height    = 164;
  832.   FileRequester.ReqGadget = &PotGadget;
  833.   FileRequester.ReqText   = &HeadingText;
  834.   FileRequester.BackFill  = 1;
  835.   FileRequester.Flags     = 0;
  836.   FileRequester.ReqBorder = &Requester3Border;
  837. } /* InitFNR */
  838.  
  839. /*
  840.  *  WaitRequester - List dirs, scroll, and set drawer and file strings until
  841.  *                  one of the LOAD(SAVE) or CANCEL buttons pushed.
  842.  */
  843. BOOL WaitRequester()
  844. {
  845.   ULONG  class = GADGETDOWN;
  846.   USHORT choice = CANCELGADGET;
  847.   struct Gadget *gadget;
  848.  
  849.   while (class != REQCLEAR)
  850.     {
  851.     if ((message=(struct IntuiMessage *) GetMsg(FRWindow->UserPort)) == 0L)
  852.       {
  853.       Wait(1L<<FRWindow->UserPort->mp_SigBit);
  854.       continue;
  855.       }
  856.     class  = message->Class;
  857.     gadget = (struct Gadget *) message->IAddress;
  858.     ReplyMsg(message);
  859.     switch (class)
  860.       {
  861.       case GADGETDOWN:
  862.            switch (gadget->GadgetID >> CLASSBITS)
  863.              {
  864.              case UPDOWNCLASS:
  865.                   ScrollList(gadget);      /* scroll up/down 1 file */
  866.                   break;
  867.              case CHOICECLASS:             /* set the name in string gads */
  868.                   if (IsParent(gadget->GadgetText->IText))
  869.                     {
  870.                     GoParent(FRFullPath);
  871.                     SetNewDrawer(&DrawerGadget, FRFullPath);
  872.                     }
  873.                   else if (IsDir(gadget->GadgetText->IText))
  874.                     {
  875.                     if (FRFullPath[strlen(FRFullPath)-1] != ':')
  876.                       strncat(FRFullPath, "/", PATHNAMELEN);
  877.                     strncat(FRFullPath, gadget->GadgetText->IText, PATHNAMELEN);
  878.                     SetNewDrawer(&DrawerGadget, FRFullPath);
  879.                     }
  880.                   else
  881.                     SetNewFile(&FileGadget,gadget->GadgetText->IText);
  882.                   break;
  883.              case BUTTONCLASS:             /* LOAD or CANCEL */
  884.                   choice = gadget->GadgetID & GADGETNUM;
  885.              }
  886.       case GADGETUP:
  887.            switch (gadget->GadgetID >> CLASSBITS)
  888.              {
  889.              case UPDOWNCLASS:             /* Potentiometer scroll */
  890.                   PotScrollList(gadget);
  891.                   break;
  892.              case STRINGCLASS:             /* They typed drawer name in */
  893.                   ThrowTrailing(DrawerString.Buffer);
  894.                   strcpy(FRFullPath,DrawerString.Buffer);
  895.                   SetNewFile(&FileGadget,"");
  896.                   ListDir(DrawerString.Buffer);
  897.                   break;
  898.              case DEVICECLASS:             /* Device change */
  899.                   ChangeDevice(gadget);
  900.              }
  901.       }
  902.     }
  903.   return((BOOL)(choice==LOAD));
  904. } /* WaitRequester */
  905.  
  906. /*
  907.  *  SetNewDrawer - Used Mouse to pick directory from selection list gadgets.
  908.  */
  909. void SetNewDrawer(Gadget,Text)
  910.   struct Gadget *Gadget;
  911.   UBYTE  *Text;
  912. {
  913.   SetNewFile(&FileGadget,"");          /* clear file name string */
  914.   SetNewFile(Gadget,Text);             /* set new drawer into gadget */
  915.   ListDir(FRFullPath);                 /* List new files into Sel List */
  916. } /* SetNewDrawer */
  917.  
  918. /*
  919.  *  SetNewFile - Copy text to gadget and refresh
  920. */
  921. void SetNewFile(gadget,Text)
  922.   struct Gadget *gadget;
  923.   UBYTE  *Text;
  924. {
  925.   struct StringInfo *strinfo;
  926.  
  927.   if (strcmp(Text, spaces30) != 0)
  928.     {
  929.     ThrowTrailing(Text);           /* get rid of trailing blanks */
  930.     strinfo = (struct StringInfo *)(gadget->SpecialInfo);
  931.     strcpy(strinfo->Buffer,Text);
  932.     RefreshGadgets(&DownGadget,FRWindow,&FileRequester);
  933.     }
  934. } /* SetNewFile */
  935.  
  936. /*
  937.  *  ListDir - List the directory into array of string names.
  938.  */
  939. void ListDir(dir)
  940.   char *dir;
  941. {
  942.   struct FileLock *my_lock, *Lock() ;
  943.  
  944.   FileCount = 0;
  945.   FirstFile = 0;
  946.  
  947.   if ((my_lock = Lock(dir, ACCESS_READ)) != NULL)
  948.     {
  949.     if (Examine(my_lock, &FileInfo))
  950.       {
  951.       strcpy(&FileListEntry[FileCount++][0], "/ Parent (dir)");
  952.       ExNext(my_lock, &FileInfo);
  953.  
  954.       while (IoErr() != ERROR_NO_MORE_ENTRIES && FileCount < MAXFILES)
  955.         {
  956.         if (strcmp(FileExt, (FileInfo.fib_FileName + strlen(FileInfo.fib_FileName) - strlen(FileExt))) == 0 || FileInfo.fib_DirEntryType > 0)
  957.            {
  958.            strcpy(&FileListEntry[FileCount][0], FileInfo.fib_FileName);
  959.            if (FileInfo.fib_DirEntryType > 0)
  960.              strcat(&FileListEntry[FileCount][0]," (dir)");
  961.            FileCount++;
  962.            }
  963.         ExNext(my_lock, &FileInfo);
  964.         }
  965.       UnLock(my_lock) ;
  966.       }
  967.     }
  968.   AttachList(FirstFile);
  969.   if (FileCount > 8)
  970.     ModifyProp(&PotGadget,FRWindow,&FileRequester,AUTOKNOB|FREEVERT|PROPBORDERLESS,0,0,0,(ULONG)0xffff*8/FileCount);
  971.   else
  972.     ModifyProp(&PotGadget,FRWindow,&FileRequester,AUTOKNOB|FREEVERT|PROPBORDERLESS,0,0,0,0xffff);
  973. } /* ListDir */
  974.  
  975. /*
  976.  *  AttachList - Attach list of file (directory) names to Selection gadgets
  977.  */
  978. void AttachList(Start)
  979.   USHORT Start;
  980. {
  981.   USHORT Gadget;
  982.  
  983.   for (Gadget = 0; Gadget <= 7 && Gadget+Start < FileCount; Gadget++)
  984.     {
  985.     strcpy(FileList[Gadget].IText,&FileListEntry[Start + Gadget][0]);
  986.     strncat(FileList[Gadget].IText, spaces30, 30-strlen(FileList[Gadget].IText));
  987.     }
  988.   for (; Gadget <= 7; Gadget++)
  989.     strcpy(FileList[Gadget].IText,spaces30);
  990.  
  991.   RefreshGadgets(&DownGadget,FRWindow,&FileRequester);
  992. } /* AttachList */
  993.  
  994. /*
  995.  *  ScrollList - Scroll the list up or down 1 file if possible
  996.  */
  997. void ScrollList(gadget)
  998.   struct Gadget *gadget;
  999. {
  1000.   ULONG VertPot = 0;
  1001.  
  1002.   switch(gadget->GadgetID & GADGETNUM)
  1003.     {
  1004.     case DOWN:
  1005.          if (FileCount > FirstFile + 8)
  1006.            ++FirstFile;
  1007.          break;
  1008.     case UP:
  1009.          if (FirstFile > 0)
  1010.            --FirstFile;
  1011.     }
  1012.   if (FileCount > 8)
  1013.     VertPot  = MIN(0xffff,((FirstFile<<16))/(FileCount-8));
  1014.   ModifyProp(&PotGadget,FRWindow,&FileRequester,AUTOKNOB|FREEVERT|PROPBORDERLESS,0,VertPot,0,KnobInfo.VertBody);
  1015.   AttachList(FirstFile);
  1016. } /* ScrollList */
  1017.  
  1018. /*
  1019.  *  PotScrollList - Calculate the file number from Pot value and attach
  1020.  *                  names to Selector List gadgets.
  1021.  */
  1022. void PotScrollList(gadget)
  1023.   struct Gadget *gadget;
  1024. {
  1025.   switch (gadget->GadgetID & GADGETNUM)
  1026.     {
  1027.     case POT:
  1028.          FirstFile = ((ULONG)(FileCount-8)*KnobInfo.VertPot+(1<<15)) >> 16;
  1029.          AttachList(FirstFile);
  1030.     }
  1031. } /* PotScrollList */
  1032.  
  1033. /*
  1034.  *  IsDir - Simple minded routine to find " (dir)" in file name
  1035.  */
  1036. BOOL IsDir(Name)
  1037.   UBYTE *Name;
  1038. {
  1039.   UBYTE *Dir;
  1040.   if (Dir = rindex(Name,'('))
  1041.     {
  1042.     ThrowTrailing(Name);
  1043.     if (strcmp(Dir,"(dir)") == 0)
  1044.       {
  1045.       *(Dir-1) = '\0';
  1046.       return(TRUE);
  1047.       }
  1048.     else
  1049.       return(FALSE);
  1050.     }
  1051.   else
  1052.     return(FALSE);
  1053. } /* IsDir */
  1054.  
  1055. /*
  1056.  *  ThrowTrailing - Remove trailing blanks from string
  1057.  */
  1058. void ThrowTrailing(String)
  1059.   UBYTE *String;
  1060. {
  1061.   SHORT I;
  1062.  
  1063.   I = strlen(String) - 1;
  1064.   while (String[I] == ' ' && I > 0)
  1065.     String[I--] = '\0';
  1066. } /* ThrowTrailing */
  1067.  
  1068. /*
  1069.  * IsParent - Check if parent chosen
  1070. */
  1071. BOOL IsParent(name)
  1072.   UBYTE *name;
  1073.   {
  1074.   ThrowTrailing(name);
  1075.   if (strcmp(name,"/ Parent (dir)") == 0)
  1076.      return (TRUE);
  1077.   else
  1078.      return (FALSE);
  1079.   } /* IsParent */
  1080.  
  1081.  
  1082. /*
  1083.  * GoParent - Change path to parent dir
  1084. */
  1085. void GoParent(dir)
  1086.   STRPTR dir;
  1087.   {
  1088.   STRPTR StrPtr;
  1089.  
  1090.   if (StrPtr = rindex(dir,'/'))
  1091.      *StrPtr = '\0';
  1092.   else if (StrPtr = rindex(dir,':'))
  1093.      *(StrPtr+1) = '\0';
  1094.   } /* GoParent */
  1095.  
  1096.  
  1097. /*
  1098.  * ChangeDevice - Change to device chosen by buttons
  1099. */
  1100. void ChangeDevice(gadget)
  1101.   struct Gadget *gadget;
  1102.   {
  1103.   UBYTE *text;
  1104.  
  1105.   text = DFGadget[gadget->GadgetID & GADGETNUM].GadgetText->IText;
  1106.   strcpy(FRFullPath, text);
  1107.   SetNewDrawer(&DrawerGadget, text);
  1108.   } /* ChangeDevice */
  1109.  
  1110.  
  1111. /*
  1112.  * ToUpper - Convert a string to all upper case
  1113. */
  1114. void ToUpper(text)
  1115.   STRPTR text;
  1116. {
  1117.   ULONG i;
  1118.  
  1119.   for (i=0 ; i < strlen(text) ; i++)
  1120.      *(text+i) = toupper(*(text+i));  /* convert character */
  1121. }  /* ToUpper */
  1122.